package KUtilities;

import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.Spring;

public class KSpringLayout extends KSpringAttributes
{
	private JComponent parent;
	private JComponent prevHeightest=null,eastMost=null,westMost=null;
	boolean vGapAdded=false;
	Spring vGap,defaultVGap,defaultHGap;
	ArrayList<Spring> vGaps;
	ArrayList<JComponent> row;
	ArrayList<JComponent> panels;
	ArrayList<ArrayList<JComponent>> column;
	
	/**
	 * Creates and Adds a SpringLayout to the Specified Component with some extra utilities
	 * @param parent : component this SpringLayout is set for
	 */
	public KSpringLayout(JComponent parent)
	{
		parent.removeAll();
		parent.setLayout(this);
		this.parent=parent;
		vGaps=new ArrayList<Spring>();
		defaultVGap=Spring.constant(0,5,15);
		defaultHGap=Spring.constant(0,5,15);
	}
	
	/**
	 * Aligns the Left Side of the components on same line
	 * @param components components to align
	 */
	public void alignLeft(JComponent...components){
		int fixed=0;
		for(int i=1;i<components.length;i++){
			int prev=getConstraint(WEST,components[fixed]).getValue();
			int curr=getConstraint(WEST,components[i]).getValue();
			if(curr<prev)
				fixed=curr;
		}
		for(int i=0;i<components.length;i++){
			if(i!=fixed)
				putConstraint(WEST,components[i],0,WEST,components[fixed]);
		}
	}
	
	/**
	 * Aligns the Right Side of the components on same line
	 * @param components components to align
	 */
	public void alignRight(JComponent...components){
		int fixed=0;
		for(int i=1;i<components.length;i++){
			int prev=getConstraint(EAST,components[fixed]).getValue();
			int curr=getConstraint(EAST,components[i]).getValue();
			if(curr>prev)
				fixed=i;
		}
		for(int i=0;i<components.length;i++){
			if(i!=fixed)
				putConstraint(EAST,components[i],0,EAST,components[fixed]);
		}
	}
	
	/**
	 * Add a row of with components given
	 * @param components components to add to row
	 */
	public void addRow(JComponent...components){
		if(column==null)
			column=new ArrayList<ArrayList<JComponent>>();
		if(row!=null)
			column.add(row);
		if(!vGapAdded)
			vGaps.add(defaultVGap);
		row=new ArrayList<JComponent>();
		KSwing.addComponents(parent,components);
		for(int i=0;i<components.length;i++)
			row.add(components[i]);
		vGapAdded=false;
	}
	
	/**
	 * Add Vertical Gap between Rows
	 * @param gap gap spring to be added
	 */
	public void addGap(Spring gap){
		if(!vGapAdded){
			vGaps.add(gap);
			vGapAdded=true;
		}
	}
	
	/**
	 * Add Vertical Gap between Rows
	 * @param gap gap to be added
	 */
	public void addGap(int gap){
		addGap(Spring.constant(gap));
	}
	
	/**
	 * Add Vertical Gap between Rows
	 * @param min Minimum gap to be added
	 * @param pref Preferred gap to be added
	 * @param max Maximum gap to be added
	 */
	public void addGap(int min,int pref,int max){
		addGap(Spring.constant(min,pref,max));
	}
	
	/**
	 * Packs the Component
	 */
	public void pack(){
		column.add(row);
		panels=new ArrayList<JComponent>();
		vGap=vGaps.get(0);
		for(int i=0;i<column.size()-1;i++){
			packRow(column.get(i),false);
			vGap=vGaps.get(i+1);
		}
		packRow(column.get(column.size()-1),true);
		
		putConstraint(WEST,westMost,defaultHGap,WEST,parent);
		putConstraint(EAST,parent,defaultHGap,EAST,eastMost);
		
	}

	/**
	 * Pack a row
	 * @param row List of components to be added to row
	 * @param last is this the last row
	 */
	private void packRow(ArrayList<JComponent> row,boolean last) {
		int heightest=0;
		for(int i=1;i<row.size();i++){
			if(getHeight(row.get(heightest)).getValue()<getHeight(row.get(i)).getValue())
				heightest=i;
			putConstraint("West",row.get(i),defaultHGap,"East",row.get(i-1));
		}
		
		for(int i=0;i<row.size();i++){
			if(i!=heightest)
				putConstraint(VERTICAL_CENTER,row.get(i),0,VERTICAL_CENTER,row.get(heightest));
		}
		
		if(prevHeightest==null)
			putConstraint(NORTH,row.get(heightest),vGap,NORTH,parent);
		else
			putConstraint(NORTH,row.get(heightest),vGap,SOUTH,prevHeightest);
		prevHeightest=row.get(heightest);
		if(last)
			putConstraint(SOUTH,parent,vGap,SOUTH,prevHeightest);
		
		int prevEast=0,currEast = 0;
		if(eastMost==null)
			eastMost=row.get(row.size()-1);
		else{
			prevEast=getConstraint(EAST,eastMost).getValue();
			currEast=getConstraint(EAST,row.get(row.size()-1)).getValue();
			if(prevEast<currEast)
				eastMost=row.get(row.size()-1);
		}

		int prevWest=0,currWest = 0;
		if(westMost==null)
			westMost=row.get(0);
		else{
			prevWest=getConstraint(WEST,westMost).getValue();
			currWest=getConstraint(WEST,row.get(0)).getValue();
			if(prevWest>currWest)
				westMost=row.get(0);
		}
	}
}
